﻿using System.Collections.Generic;
using System.IO;
using UnityEditor;
using UnityEngine;

namespace Jerry
{
    public class BuildScript
    {
        private static bool useManifest = false;

        /// <summary>
        /// 全部重打
        /// </summary>
        [MenuItem("Assets/JerryAB/RebuildAssetBundles")]
        public static void RebuildAssetBundles()
        {
            if (EditorUtility.DisplayDialog("确认全部重打？",
                "确认全部重打？",
                "是",
                "否"))
            {
                string outputPath = Path.Combine(PlatformUtil.AssetBundlesOutputPath, PlatformUtil.CurPlatform.ToString());
                if (Directory.Exists(outputPath))
                {
                    Directory.Delete(outputPath, true);
                }
                DoBuildAssetBundles();
                Debug.LogFormat("全部资源打包完毕 {0} {1}", PlatformUtil.CurPlatform.ToString(), PlatformUtil.CurTime());
            }
        }

        /// <summary>
        /// 增量打
        /// </summary>
        [MenuItem("Assets/JerryAB/BuildAssetBundles")]
        public static void BuildAssetBundles()
        {
            DoBuildAssetBundles();
            Debug.LogFormat("增量资源打包完毕 {0} {1}", PlatformUtil.CurPlatform.ToString(), PlatformUtil.CurTime());
        }

        /// <summary>
        /// 拷贝所有资源
        /// </summary>
        [MenuItem("Assets/JerryAB/CopyAssetBundles")]
        public static void CopyAssetBundles()
        {
            if (DoCopyAssetBundles())
            {
                Debug.LogFormat("资源拷贝完毕 {0} {1}", PlatformUtil.CurPlatform.ToString(), PlatformUtil.CurTime());
            }
            else
            {
                Debug.LogFormat("资源拷贝<color=red>失败</color> {0} {1}", PlatformUtil.CurPlatform.ToString(), PlatformUtil.CurTime());
            }
        }

        /// <summary>
        /// 拷贝ResVer.txt里的资源
        /// </summary>
        [MenuItem("Assets/JerryAB/CopyAssetBundles_ResVer")]
        public static void CopyAssetBundles_ResVer()
        {
            TextAsset txt = Resources.Load<TextAsset>("ResVer");
            List<string> nameList = new List<string>();
            if (useManifest)
            {
                nameList.Add(PlatformUtil.CurPlatform.ToString());
            }
            BundleInfoMgr mgr = JsonUtility.FromJson<BundleInfoMgr>(txt.text);
            foreach (BundleInfo info in mgr.InfoList)
            {
                nameList.Add(info.name);
            }
            if (DoCopyAssetBundles(nameList))
            {
                Debug.LogFormat("版本文件内资源拷贝完毕 {0} {1}", PlatformUtil.CurPlatform.ToString(), PlatformUtil.CurTime());
            }
            else
            {
                Debug.LogFormat("版本文件内资源拷贝<color=red>失败</color> {0} {1}", PlatformUtil.CurPlatform.ToString(), PlatformUtil.CurTime());
            }
        }

        [MenuItem("Assets/JerryAB/CleanAssetBundlesCache")]
        public static void CleanAssetBundlesCache()
        {
            Caching.CleanCache();
            Debug.LogFormat("清理缓存资源完毕 {0} {1}", PlatformUtil.CurPlatform.ToString(), PlatformUtil.CurTime());
        }

        [MenuItem("Assets/JerryAB/CleanPersistentData")]
        public static void CleanPersistentData()
        {
            string pDP = PlatformUtil.GetPersistentDataPath();
            Directory.Delete(pDP, true);
            Debug.LogFormat("清理PersistentData资源完毕 {0} {1}", PlatformUtil.CurPlatform.ToString(), PlatformUtil.CurTime());
        }

        /// <summary>
        /// 拷贝ResVer.txt文件
        /// </summary>
        [MenuItem("Assets/JerryAB/CopyResVer")]
        public static void CopyResVer()
        {
            string pathFrom = Path.Combine(GetResVerPath(), "ResVer.json");
            if (!File.Exists(pathFrom))
            {
                PlatformUtil.Log("无法找到ResVer.json");
                return;
            }
            string pathTo = Path.Combine(Application.dataPath, "Resources/ResVer.json");
            File.Copy(pathFrom, pathTo, true);
            AssetDatabase.SaveAssets();
            AssetDatabase.Refresh();
            Debug.LogFormat("CopyResVer完毕 {0} {1}", PlatformUtil.CurPlatform.ToString(), PlatformUtil.CurTime());
        }

        private static void DoBuildAssetBundles()
        {
            string outputPath = Path.Combine(PlatformUtil.AssetBundlesOutputPath, PlatformUtil.CurPlatform.ToString());
            if (!Directory.Exists(outputPath))
            {
                Directory.CreateDirectory(outputPath);
            }
            BuildPipeline.BuildAssetBundles(outputPath, BuildAssetBundleOptions.None, EditorUserBuildSettings.activeBuildTarget);
        }

        /// <summary>
        /// 执行资源拷贝
        /// </summary>
        /// <param name="fileNameCheck"></param>
        /// <param name="fileNameNotFilter"></param>
        /// <returns>是否成功</returns>
        private static bool DoCopyAssetBundles(List<string> fileNameCheck = null, List<string> fileNameNotFilter = null)
        {
            string pathFrom = Path.Combine(GetAssetBundlesOutputPath(), PlatformUtil.CurPlatform.ToString());
            if (!Directory.Exists(pathFrom))
            {
                PlatformUtil.Log(string.Format("无法找到资源工程中{0}平台的资源输出目录", PlatformUtil.CurPlatform.ToString()));
                return false;
            }

            CleanAssetBundlesCache();
            CleanPersistentData();

            string pathTo = Path.Combine(Application.streamingAssetsPath, PlatformUtil.CurPlatform.ToString());

            if (fileNameNotFilter == null)
            {
                fileNameNotFilter = new List<string>();
            }
            fileNameNotFilter.Add(".manifest");
            fileNameNotFilter.Add(".meta");
            List<string> fileNameNotCheck = new List<string>();
            if (!useManifest)
            {
                fileNameCheck.Add(PlatformUtil.CurPlatform.ToString());
            }
            CopyDirectory(pathFrom, pathTo, true, fileNameCheck, null, fileNameNotCheck, fileNameNotFilter);
            AssetDatabase.SaveAssets();
            AssetDatabase.Refresh();
            return true;
        }

        private static string GetResVerPath()
        {
            string pathFrom = Application.dataPath + "/../../";
            string ret = pathFrom + string.Format("{0}/", "Art");//默认地址

            if (Directory.Exists(ret) == false)
            {
                string[] directs = Directory.GetDirectories(pathFrom);
                string directName;
                foreach (string direct in directs)
                {
                    directName = Path.GetFileName(direct);
                    if (directName.Contains("Art") || directName.Contains("art"))
                    {
                        ret = pathFrom + string.Format("{0}/", directName);
                        if (Directory.Exists(ret))
                        {
                            break;
                        }
                    }
                }
            }
            if (!Directory.Exists(ret))
            {
                PlatformUtil.Log("无法找到资源工程的版本控制文件目录");
            }
            return ret;
        }

        private static string GetAssetBundlesOutputPath()
        {
            string pathFrom = Application.dataPath + "/../../";
            string ret = pathFrom + string.Format("{0}/{1}/", "Art", PlatformUtil.AssetBundlesOutputPath);//默认地址
            if (Directory.Exists(ret) == false)
            {
                string[] directs = Directory.GetDirectories(pathFrom);
                string directName;
                foreach (string direct in directs)
                {
                    directName = Path.GetFileName(direct);
                    if (directName.Contains("Art") || directName.Contains("art"))
                    {
                        ret = pathFrom + string.Format("{0}/{1}/", directName, PlatformUtil.AssetBundlesOutputPath);
                        if (Directory.Exists(ret))
                        {
                            break;
                        }
                    }
                }
            }
            if (!Directory.Exists(ret))
            {
                PlatformUtil.Log("无法找到资源工程的资源输出目录");
            }
            return ret;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="pathFrom"></param>
        /// <param name="pathTo"></param>
        /// <param name="clean"></param>
        /// <param name="fileNameCheck">只要这个列表里包含的文件名</param>
        /// <param name="fileNameFilter">文件名包含这个列表的所有特征</param>
        /// <param name="fileNameNotCheck">这个列表里的不要</param>
        /// <param name="fileNameNotFilter">文件名不包含这个列表的任意特征</param>
        private static void CopyDirectory(string pathFrom, string pathTo, bool clean = false, List<string> fileNameCheck = null,
            List<string> fileNameFilter = null, List<string> fileNameNotCheck = null, List<string> fileNameNotFilter = null)
        {
            if (string.IsNullOrEmpty(pathFrom) ||
                string.IsNullOrEmpty(pathTo))
            {
                return;
            }

            if (Directory.Exists(pathFrom) == false)
            {
                return;
            }

            if (clean)
            {
                if (Directory.Exists(pathTo))
                {
                    Directory.Delete(pathTo, true);
                }
                Directory.CreateDirectory(pathTo);
            }
            else
            {
                if (!Directory.Exists(pathTo))
                {
                    Directory.CreateDirectory(pathTo);
                }
            }

            string[] files = Directory.GetFiles(pathFrom);
            string fileName;
            foreach (string file in files)
            {
                fileName = Path.GetFileName(file);
                if (FileNameFilter(fileName, fileNameFilter, true) == false
                    || FileNameFilter(fileName, fileNameNotFilter, false) == false
                    || (fileNameCheck != null && !fileNameCheck.Contains(fileName))
                    || (fileNameNotCheck != null && fileNameNotCheck.Contains(fileName)))
                {
                    continue;
                }
                //不做删除的话，同名文件，只是大小写不一样，文件名不会替换
                if (File.Exists(pathTo + "/" + fileName))
                {
                    File.Delete(pathTo + "/" + fileName);
                }
                File.Copy(pathFrom + "/" + fileName, pathTo + "/" + fileName, true);
            }

            string[] directs = Directory.GetDirectories(pathFrom);
            string directName;
            foreach (string direct in directs)
            {
                directName = Path.GetFileName(direct);
                CopyDirectory(direct, pathTo + "/" + directName, clean, fileNameCheck, fileNameFilter, fileNameNotCheck, fileNameNotFilter);
            }
        }

        /// <summary>
        /// 文件名过滤
        /// </summary>
        /// <param name="fileName"></param>
        /// <param name="fileNameFilter"></param>
        /// <param name="include"></param>
        /// <returns>通过</returns>
        private static bool FileNameFilter(string fileName, List<string> fileNameFilter = null, bool include = true)
        {
            if (fileNameFilter == null
                || fileNameFilter.Count <= 0
                || string.IsNullOrEmpty(fileName))
            {
                return true;
            }
            foreach (string filter in fileNameFilter)
            {
                if (include)
                {
                    if (!fileName.Contains(filter))
                    {
                        return false;
                    }
                }
                else
                {
                    if (fileName.Contains(filter))
                    {
                        return false;
                    }
                }
            }
            return true;
        }
    }
}